package cn.fanyc.action.blockchain.fbc.contract;

import cn.fanyc.action.blockchain.fbc.contract.api.State;
import org.hyperledger.fabric.contract.annotation.DataType;
import org.hyperledger.fabric.contract.annotation.Property;
import org.json.JSONObject;
import org.json.JSONPropertyIgnore;

import java.util.StringJoiner;

import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * 单张商业票据对象
 *
 * @author Fanyc
 * @date 2020-10-19 17:15
 */
@DataType
public class Paper extends State {

    /**
     * 票据状态定义：已发行
     */
    public static final String ISSUED = "ISSUED";
    /**
     * 票据状态定义：交易中
     */
    public static final String TRADING = "TRADING";
    /**
     * 票据状态定义：已回收
     */
    public static final String REDEEMED = "REDEEMED";

    /**
     * 票据号
     */
    @Property
    private String paperNumber;
    /**
     * 发布者
     */
    @Property
    private String issuer;
    /**
     * 发布日期
     */
    @Property
    private String issueDateTime;
    /**
     * 票面金额
     */
    @Property
    private int faceValue;
    /**
     * 结束日期
     */
    @Property
    private String maturityDateTime;
    /**
     * 拥有者
     */
    @Property
    private String owner;
    /**
     * 票据状态
     */
    @Property
    private String state = "";

    /**
     * 当前票据是否为发行状态
     *
     * @return 是否发行状态
     */
    @JSONPropertyIgnore
    public boolean isIssued() {
        return ISSUED.equals(this.state);
    }

    /**
     * 当前票据是否交易状态
     *
     * @return 是否交易状态
     */
    @JSONPropertyIgnore
    public boolean isTrading() {
        return TRADING.equals(this.state);
    }

    /**
     * 当前票据是否回收状态
     *
     * @return 是否回收状态
     */
    @JSONPropertyIgnore
    public boolean isRedeemed() {
        return REDEEMED.equals(this.state);
    }

    /**
     * 设置为发布状态
     *
     * @return 当前票据对象
     */
    public Paper setIssued() {
        this.state = ISSUED;
        return this;
    }

    /**
     * 设置为交易状态
     *
     * @return 当前票据对象
     */
    public Paper setTrading() {
        this.state = TRADING;
        return this;
    }

    /**
     * 设置为回收状态
     *
     * @return 当前票据对象
     */
    public Paper setRedeemed() {
        this.state = REDEEMED;
        return this;
    }

    /**
     * 设置票据的上链Key
     *
     * @return 当前票据对象
     */
    public Paper setKey() {
        this.key = State.makeKey(new String[]{this.issuer, this.paperNumber});
        return this;
    }

    /**
     * 将字节数组转换为票据对象
     *
     * @param data 字节数组
     * @return 票据对象
     */
    public static Paper deserialize(byte[] data) {
        // 先转换为JSON对象
        JSONObject jsonObject = new JSONObject(new String(data, UTF_8));
        // 获取票据各个属性值
        String issuer = jsonObject.getString("issuer");
        String paperNumber = jsonObject.getString("paperNumber");
        String issueDateTime = jsonObject.getString("issueDateTime");
        String maturityDateTime = jsonObject.getString("maturityDateTime");
        int faceValue = jsonObject.getInt("faceValue");
        String owner = jsonObject.getString("owner");
        String state = jsonObject.getString("state");
        // 构造票据对象
        return createInstance(issuer, paperNumber, issueDateTime, maturityDateTime, faceValue, owner, state);
    }

    /**
     * 构造票据实例
     * @param issuer 发布者
     * @param paperNumber 票据号
     * @param issueDateTime 发布日期
     * @param maturityDateTime 结束日期
     * @param faceValue 票面金额
     * @param owner 拥有者
     * @param state 票据状态
     * @return 票据对象
     */
    public static Paper createInstance(String issuer, String paperNumber, String issueDateTime,
                                                 String maturityDateTime, int faceValue, String owner, String state) {
        return new Paper()
                .setIssuer(issuer)
                .setPaperNumber(paperNumber)
                .setIssueDateTime(issueDateTime)
                .setMaturityDateTime(maturityDateTime)
                .setFaceValue(faceValue)
                .setOwner(owner)
                .setState(state)
                .setKey();
    }

    /**
     * 字符串输出
     *
     * @return 字符串
     */
    @Override
    public String toString() {
        return new StringJoiner(", ", Paper.class.getSimpleName() + "[", "]")
                .add("state='" + state + "'")
                .add("paperNumber='" + paperNumber + "'")
                .add("issuer='" + issuer + "'")
                .add("issueDateTime='" + issueDateTime + "'")
                .add("faceValue=" + faceValue)
                .add("maturityDateTime='" + maturityDateTime + "'")
                .add("owner='" + owner + "'")
                .toString();
    }

    //////////////////// Getter/Setter ////////////////////

    /**
     * 获取paperNumber
     *
     * @return 返回paperNumber
     */
    public String getPaperNumber() {
        return paperNumber;
    }

    /**
     * 设置paperNumber的值
     *
     * @param paperNumber 要设置的值
     * @return 当前对象
     */
    public Paper setPaperNumber(String paperNumber) {
        this.paperNumber = paperNumber;
        return this;
    }

    /**
     * 获取issuer
     *
     * @return 返回issuer
     */
    public String getIssuer() {
        return issuer;
    }

    /**
     * 设置issuer的值
     *
     * @param issuer 要设置的值
     * @return 当前对象
     */
    public Paper setIssuer(String issuer) {
        this.issuer = issuer;
        return this;
    }

    /**
     * 获取issueDateTime
     *
     * @return 返回issueDateTime
     */
    public String getIssueDateTime() {
        return issueDateTime;
    }

    /**
     * 设置issueDateTime的值
     *
     * @param issueDateTime 要设置的值
     * @return 当前对象
     */
    public Paper setIssueDateTime(String issueDateTime) {
        this.issueDateTime = issueDateTime;
        return this;
    }

    /**
     * 获取faceValue
     *
     * @return 返回faceValue
     */
    public int getFaceValue() {
        return faceValue;
    }

    /**
     * 设置faceValue的值
     *
     * @param faceValue 要设置的值
     * @return 当前对象
     */
    public Paper setFaceValue(int faceValue) {
        this.faceValue = faceValue;
        return this;
    }

    /**
     * 获取maturityDateTime
     *
     * @return 返回maturityDateTime
     */
    public String getMaturityDateTime() {
        return maturityDateTime;
    }

    /**
     * 设置maturityDateTime的值
     *
     * @param maturityDateTime 要设置的值
     * @return 当前对象
     */
    public Paper setMaturityDateTime(String maturityDateTime) {
        this.maturityDateTime = maturityDateTime;
        return this;
    }

    /**
     * 获取owner
     *
     * @return 返回owner
     */
    public String getOwner() {
        return owner;
    }

    /**
     * 设置owner的值
     *
     * @param owner 要设置的值
     * @return 当前对象
     */
    public Paper setOwner(String owner) {
        this.owner = owner;
        return this;
    }

    /**
     * 获取state
     *
     * @return 返回state
     */
    public String getState() {
        return state;
    }

    /**
     * 设置state的值
     *
     * @param state 要设置的值
     * @return 当前对象
     */
    public Paper setState(String state) {
        this.state = state;
        return this;
    }
}
